﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data;
using System.Data.Metadata.Edm;

namespace BLL
{
    public static class BaseExtensions
    {
        public static void SetAllModified<T>(this T entity, ObjectContext context) where T : IEntityWithKey
        {
            ObjectStateEntry stateEntry = context.ObjectStateManager.GetObjectStateEntry(entity.EntityKey);
            IEnumerable<string> propertyNameList = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(pn => pn.FieldType.Name);
            foreach (string propName in propertyNameList)
            {
                stateEntry.SetModifiedProperty(propName);
            }
        }

        //public static void AttachUpdated(this ObjectContext context, EntityObject objectDetacted)
        //{
        //    if (objectDetacted.EntityState == EntityState.Detached)
        //    {
        //        object currentEntityInDb = null;
        //        if (!context.TryGetObjectByKey(objectDetacted.EntityKey, out currentEntityInDb))
        //        {
        //            throw new ObjectNotFoundException();
        //        }
        //        context.ApplyReferencePropertyChanges((IEntityWithRelationships)objectDetacted, (IEntityWithRelationships)currentEntityInDb);
        //        context.ApplyCurrentValues(objectDetacted.EntityKey.EntitySetName, objectDetacted);
        //    }
        //}

        public static void ApplyReferencePropertyChanges(this ObjectContext context, IEntityWithRelationships newEntity, IEntityWithRelationships oldEntity)
        {
            foreach (IRelatedEnd relatedEnd in oldEntity.RelationshipManager.GetAllRelatedEnds())
            {
                EntityReference oldRef = relatedEnd as EntityReference;
                if (oldRef != null)
                {
                    EntityReference newRef = newEntity.RelationshipManager.GetRelatedEnd(oldRef.RelationshipName, oldRef.TargetRoleName) as EntityReference;
                    oldRef.EntityKey = newRef.EntityKey;
                }
            }
        }

        public static string GetEntitySetFullName(ObjectContext context, string entityTypeName)
        {
            var container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
            string entitySetName = (
                from meta in container.BaseEntitySets
                where meta.ElementType.Name == entityTypeName
                select meta.Name
                ).First();
            return container.Name + "." + entitySetName;
        }

        //public static string GetEntitySetName(this ObjectContext context, Type entityType)
        //{
        //    if (context == null)
        //    {
        //        throw new ArgumentNullException("context");
        //    }
        //    if (entityType == null)
        //    {
        //        throw new ArgumentNullException("entityType");
        //    }

        //    Type nonProxyEntityType = ObjectContext.GetObjectType(entityType);
        //    if (entityType == null)
        //    {
        //        return null;
        //    }

        //    var container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, System.Data.Metadata.Edm.DataSpace.CSpace);
        //    var result = (from entitySet in container.BaseEntitySets
        //                  where entitySet.ElementType.Name.Equals(nonProxyEntityType.Name)
        //                  select entitySet.Name).SingleOrDefault();
        //    if (string.IsNullOrEmpty(result))
        //    {
        //        return null;
        //    }
        //    return result;
        //}
    }
}
